#!/bin/bash
LOCAL_PASSFILE="/etc/openvpn/server/userlist.txt"
LOG_FILE="/var/log/openvpn/openvpn-login.log"
TIME_STAMP=$(date "+%Y-%m-%d %T")

LDAP_SERVER="ldap://127.0.0.1:389"
LDAP_BIND_DN="cn=admin,dc=hei,dc=com"
LDAP_BIND_PW="123456"
LDAP_USER_BASE="cn=admin,dc=hei,dc=com"
LDAP_USER_FILTER="(uid=\${username})"

mkdir -p "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"
chmod 600 "$LOG_FILE"


if [ -z "$username" ] || [ -z "$password" ]; then
    echo "${TIME_STAMP}: ERROR - Missing username or password." >> "$LOG_FILE"
    exit 1
fi

check_local_user() {
    if [ ! -r "$LOCAL_PASSFILE" ]; then
        echo "${TIME_STAMP}: WARNING - Local password file not found: ${LOCAL_PASSFILE}" >> "$LOG_FILE"
        return 1
    fi
    CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${LOCAL_PASSFILE}`

    if [ "${CORRECT_PASSWORD}" = "" ]; then 
          echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
            return 1
    fi

    if [ "$password" = "$CORRECT_PASSWORD" ]; then 
        echo "${TIME_STAMP}: LOCAL SUCCESS: username=\"${username}\"" >> "$LOG_FILE"
        exit 0
    fi

    echo "${TIME_STAMP}: LOCAL FAIL - Incorrect password: ${username}" >> "$LOG_FILE"
    return 1
}

check_ldap_user() {
    LDAP_CMD="ldapsearch -x -H \"$LDAP_SERVER\" "
    LDAP_CMD+="-D \"$LDAP_BIND_DN\" -w \"$LDAP_BIND_PW\" "
    LDAP_CMD+="-b \"$LDAP_USER_BASE\" "
    LDAP_CMD+="\"$LDAP_USER_FILTER\" 2>/dev/null"
    LDAP_RESULT=$(eval "$LDAP_CMD")
    
    if echo "$LDAP_RESULT" | grep -qE "^dn: .*"; then
        USER_DN=$(echo "$LDAP_RESULT" | awk '/^dn: / {print $2; exit}')
        
        if ldapwhoami -x -H "$LDAP_SERVER" -D "$USER_DN" -w "$password" >/dev/null 2>&1; then
            echo "${TIME_STAMP}: LDAP SUCCESS: username=\"${username}\"" >> "$LOG_FILE"
            exit 0
        else
            echo "${TIME_STAMP}: LDAP FAIL - Invalid credentials: ${username}" >> "$LOG_FILE"
            return 1
        fi
    else
        echo "${TIME_STAMP}: LDAP FAIL - User not found: ${username}" >> "$LOG_FILE"
        return 1
    fi
}

(
    if check_local_user; then
        exit 0
    fi

    if check_ldap_user; then
        exit 0
    fi
    echo "${TIME_STAMP}: GLOBAL FAIL - All auth methods failed for: ${username}" >> "$LOG_FILE"
    exit 1
)